feat(models): add typed model classes for TableBlock cells and column_settings - #1939
feat(models): add typed model classes for TableBlock cells and column_settings#1939srtaalej wants to merge 6 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1939 +/- ##
==========================================
- Coverage 84.17% 84.11% -0.07%
==========================================
Files 118 118
Lines 13425 13442 +17
==========================================
+ Hits 11301 11307 +6
- Misses 2124 2135 +11 ☔ View full report in Codecov by Harness. |
| class RichTextCell(JsonObject): | ||
| """A rich_text typed cell for use in TableBlock rows.""" | ||
|
|
||
| type = "rich_text" | ||
|
|
||
| @property | ||
| def attributes(self) -> Set[str]: | ||
| return {"type", "elements"} | ||
|
|
||
| def __init__( | ||
| self, | ||
| *, | ||
| elements: Sequence[Union[Dict[str, Any], Any]], | ||
| **others: dict, | ||
| ): | ||
| """A rich text cell used in table block rows. | ||
| https://docs.slack.dev/reference/block-kit/blocks/table-block | ||
|
|
||
| Args: | ||
| elements (required): An array of rich text element objects | ||
| (rich_text_section, rich_text_list, rich_text_quote, rich_text_preformatted). | ||
| """ | ||
| show_unknown_key_warning(self, others) | ||
| self.type = self.__class__.type | ||
| from slack_sdk.models.blocks.block_elements import BlockElement | ||
|
|
||
| self.elements = BlockElement.parse_all(elements) | ||
|
|
||
| @classmethod | ||
| def parse(cls, cell: Optional[Union[Dict[str, Any], "RichTextCell"]]) -> Optional["RichTextCell"]: | ||
| if cell is None: | ||
| return None | ||
| if isinstance(cell, RichTextCell): | ||
| return cell | ||
| if isinstance(cell, dict): | ||
| d = {k: v for k, v in cell.items() if k != "type"} | ||
| return RichTextCell(**d) | ||
| return None | ||
|
|
||
|
|
There was a problem hiding this comment.
| class RichTextCell(JsonObject): | |
| """A rich_text typed cell for use in TableBlock rows.""" | |
| type = "rich_text" | |
| @property | |
| def attributes(self) -> Set[str]: | |
| return {"type", "elements"} | |
| def __init__( | |
| self, | |
| *, | |
| elements: Sequence[Union[Dict[str, Any], Any]], | |
| **others: dict, | |
| ): | |
| """A rich text cell used in table block rows. | |
| https://docs.slack.dev/reference/block-kit/blocks/table-block | |
| Args: | |
| elements (required): An array of rich text element objects | |
| (rich_text_section, rich_text_list, rich_text_quote, rich_text_preformatted). | |
| """ | |
| show_unknown_key_warning(self, others) | |
| self.type = self.__class__.type | |
| from slack_sdk.models.blocks.block_elements import BlockElement | |
| self.elements = BlockElement.parse_all(elements) | |
| @classmethod | |
| def parse(cls, cell: Optional[Union[Dict[str, Any], "RichTextCell"]]) -> Optional["RichTextCell"]: | |
| if cell is None: | |
| return None | |
| if isinstance(cell, RichTextCell): | |
| return cell | |
| if isinstance(cell, dict): | |
| d = {k: v for k, v in cell.items() if k != "type"} | |
| return RichTextCell(**d) | |
| return None |
🪓 note: I think here we can use the existing RichTextBlock similar to @slack/types implementation:
| return len(self.text) >= 1 | ||
|
|
||
|
|
||
| class ColumnSettings(JsonObject): |
There was a problem hiding this comment.
| class ColumnSettings(JsonObject): | |
| class TableBlockColumnSettings(JsonObject): |
📣 note: Hoping to namespace this to match the @slack/types package too but also to avoid confusion on which columns this settings are applied:
👾 note: Please know I'm less confident about this change so consider it a non-blocking preference!
|
|
||
| def test_with_rich_text_cell_objects(self): | ||
| """Test table using typed RichTextBlock objects""" | ||
| cell = RichTextBlock(elements=[{"type": "rich_text_section", "elements": [{"type": "text", "text": "Hello"}]}]) |
There was a problem hiding this comment.
🪬 suggestion: Let's strengthen the parsing checks of this test with rich text elements too!
| cell = RichTextBlock(elements=[{"type": "rich_text_section", "elements": [{"type": "text", "text": "Hello"}]}]) | |
| cell = RichTextBlock( | |
| elements=[RichTextSectionElement(elements=[RichTextElementParts.Text(text="Hello")])] | |
| ) |
| return len(self.text) >= 1 | ||
|
|
||
|
|
||
| class TableBlockColumnSettings(JsonObject): |
There was a problem hiding this comment.
🧮 question: I'm curious if keeping this beside the TableBlock implementation is best? Or if it's right to keep here? AFAICT we won't share these settings with other blocks...
Summary
Adds typed model classes for
TableBlockcells and column settings, so developers get autocomplete and validation instead of hand-building dicts.TableBlockColumnSettings— typed class for column settings withalignandis_wrappedRichTextBlock(pre-existing) — already coversrich_texttable cellsRawTextObject(pre-existing) — already coversraw_textcellsTableBlocktype annotations are widened to accept both typed objects and raw dicts for full backward compatibility.Closes #1938
Testing
Test app.py
Requirements